﻿//<TunynetCopyright>
//--------------------------------------------------------------
//<copyright>青岛拓宇网络科技有限公司 2005-2008</copyright>
//<version>V0.5</verion>
//<createdate>2008-3-29</createdate>
//<author>mazq</author>
//<email>mazq@tunynet.com</email>
//<log date="2008-3-29">创建</log>
//--------------------------------------------------------------
//</TunynetCopyright>


using System;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using System.Web;

namespace ChinaCustoms.Qingdao.Workflow.Controls
{
    /// <summary>
    /// 分页控件
    /// </summary>
    public class Pager : WebControl, INamingContainer, IPager
    {
        Label totalSummaryControl = new Label();
        Label pagerItemsControl = new Label();

        protected override void OnPreRender(EventArgs e)
        {
            if (ShowTotalSummary && TotalPages > 0)
            {
                this.Controls.Add(totalSummaryControl);
                if (!string.IsNullOrEmpty(TotalSummaryCssClass))
                    totalSummaryControl.CssClass = TotalSummaryCssClass;

                BindTotalSummary(totalSummaryControl);
            }

            if (ShowPagerItems && TotalPages > 1)
            {
                this.Controls.Add(pagerItemsControl);
                if (!string.IsNullOrEmpty(PagerItemsCssClass))
                    pagerItemsControl.CssClass = PagerItemsCssClass;

                if (ShowFirst)
                    BindFirst(pagerItemsControl);

                if (ShowPrevious)
                    BindPrevious(pagerItemsControl);

                if (ShowNumeric)
                    BindPages(pagerItemsControl);

                if (ShowNext)
                    BindNext(pagerItemsControl);

                if (ShowLast)
                    BindLast(pagerItemsControl);
            }

            base.OnPreRender(e);
        }


        /// <summary>
        /// 分页摘要 css
        /// </summary>
        public string TotalSummaryCssClass
        {
            get { return ViewState["TotalSummaryCssClass"] as string ?? string.Empty; }
            set { ViewState["TotalSummaryCssClass"] = value; }
        }

        /// <summary>
        /// 分页按钮 css
        /// </summary>
        public string PagerItemsCssClass
        {
            get { return ViewState["PagerItemsCssClass"] as string ?? string.Empty; }
            set { ViewState["PagerItemsCssClass"] = value; }
        }


        /// <summary>
        /// PageIndex QueryString 名称
        /// </summary>
        public string PageIndexQueryString
        {
            get { return ViewState["PageIndexQueryString"] as string ?? "PageIndex"; }
            set { ViewState["PageIndexQueryString"] = value; }
        }

        /// <summary>
        /// 是否显示分页摘要
        /// </summary>
        public virtual bool ShowTotalSummary
        {
            get { return (bool)(ViewState["ShowTotalSummary"] ?? false); }
            set { ViewState["ShowTotalSummary"] = value; }
        }

        /// <summary>
        /// 是否显示分页按钮
        /// </summary>
        public virtual bool ShowPagerItems
        {
            get { return (bool)(ViewState["ShowPagerItems"] ?? true); }
            set { ViewState["ShowPagerItems"] = value; }
        }

        /// <summary>
        /// 显示数字形式按钮的数量
        /// </summary>
        public virtual int NumericPageButtonCount
        {
            get { return (int)(ViewState["NumericPageButtonCount"] ?? 10); }
            set { ViewState["NumericPageButtonCount"] = value; }
        }

        /// <summary>
        /// 分页按钮
        /// </summary>
        public virtual PagerMode Mode
        {
            get
            {
                object pagerModeViewState = ViewState["PagerMode"];
                if (pagerModeViewState != null)
                    return (PagerMode)((int)pagerModeViewState);
                else
                    return PagerMode.NumericNextPreviousFirstLast;
            }
            set { ViewState["PagerMode"] = (int)value; }
        }

        string _pagerButtonUrlPattern = null;
        public string PagerButtonUrlPattern
        {
            get { return _pagerButtonUrlPattern; }
            set { _pagerButtonUrlPattern = value; }
        }


        #region Help Properties & Methods

        /// <summary>
        /// 绑定 分页摘要
        /// </summary>
        protected virtual void BindTotalSummary(Control c)
        {
            c.Controls.Add(new LiteralControl(string.Format("第{1}页/共{0}页 [共{2}条记录]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", this.TotalPages, this.CurrentPage, this.TotalRecords)));
        }

        /// <summary>
        /// Binds the first pager link.
        /// </summary>
        protected virtual void BindFirst(Control c)
        {
            if ((PageIndex >= 3) && (TotalPages > this.NumericPageButtonCount))
            {
                HyperLink link = new HyperLink();
                link.ID = "First";
                link.Text = "&lt;&lt;";
                link.NavigateUrl = GetPageNavigateUrl(1);
                c.Controls.Add(link);

                if (ShowNumeric || (ShowPrevious && PageIndex > 0) || ShowLast)
                    c.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
            }
        }

        /// <summary>
        /// Binds the last pager link.
        /// </summary>
        protected virtual void BindLast(Control c)
        {
            if (((PageIndex + 3) < TotalPages) && (TotalPages > this.NumericPageButtonCount))
            {
                if (ShowNumeric || (ShowNext && (PageIndex + 1 < TotalPages)))
                    c.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));

                HyperLink link = new HyperLink();
                link.ID = "Last";
                link.Text = "&gt;&gt;";
                link.NavigateUrl = GetPageNavigateUrl(TotalPages);
                c.Controls.Add(link);
            }
        }

        /// <summary>
        /// Binds the previous pager link.
        /// </summary>
        protected virtual void BindPrevious(Control c)
        {
            if (PageIndex > 0)
            {
                HyperLink link = new HyperLink();
                link.ID = "Prev";
                link.Text = "上一页";
                link.NavigateUrl = GetPageNavigateUrl(PageIndex);
                c.Controls.Add(link);

                if (ShowNumeric || ShowLast || (ShowNext && (PageIndex + 1 < TotalPages)))
                    c.Controls.Add(new LiteralControl("&nbsp;"));
            }
        }

        /// <summary>
        /// Binds the next pager link.
        /// </summary>
        protected virtual void BindNext(Control c)
        {
            if (PageIndex + 1 < TotalPages)
            {
                if (ShowNumeric)
                    c.Controls.Add(new LiteralControl("&nbsp;"));

                HyperLink link = new HyperLink();
                link.ID = "Next";
                link.Text = "下一页";
                link.NavigateUrl = GetPageNavigateUrl(PageIndex + 2);
                c.Controls.Add(link);
            }
        }

        /// <summary>
        /// Binds the individual page links.
        /// </summary>
        protected virtual void BindPages(Control c)
        {
            HyperLink link;

            int start = GetFirstNumericPageIndex();
            int end = GetLastNumericPageIndex();

            for (int i = start; i <= end; i++)
            {
                if (PageIndex == i)
                {
                    c.Controls.Add(new LiteralControl("<span class=\"currentPage\">" + (i + 1).ToString() + "</span>"));
                }
                else
                {
                    link = new HyperLink();
                    link.EnableViewState = false;
                    link.Text = (i + 1).ToString();
                    link.NavigateUrl = GetPageNavigateUrl(i + 1);
                    c.Controls.Add(link);
                }

                if (i < end)
                    c.Controls.Add(new LiteralControl("&nbsp;"));
            }
        }

        /// <summary>
        /// 获取第一个数字分页按钮
        /// </summary>
        protected virtual int GetFirstNumericPageIndex()
        {
            if (this.TotalPages < this.NumericPageButtonCount || this.PageIndex - (this.NumericPageButtonCount / 2) < 0)
                return 0;
            else if (this.PageIndex + (this.NumericPageButtonCount / 2) >= this.TotalPages)
                return this.TotalPages - this.NumericPageButtonCount;
            else
                return this.PageIndex - (this.NumericPageButtonCount / 2);
        }

        /// <summary>
        /// 获取最后一个数字分页按钮
        /// </summary>
        protected virtual int GetLastNumericPageIndex()
        {
            int lastBuffer = this.NumericPageButtonCount / 2;
            if (this.NumericPageButtonCount % 2 == 0)
                lastBuffer--;

            if (this.TotalPages < this.NumericPageButtonCount || this.PageIndex + lastBuffer >= this.TotalPages)
                return this.TotalPages - 1;
            else if (this.PageIndex - (this.NumericPageButtonCount / 2) < 0)
                return this.NumericPageButtonCount - 1;
            else
                return this.PageIndex + lastBuffer;
        }

        protected virtual string GetPageNavigateUrl(int pageIndex)
        {
            if (!string.IsNullOrEmpty(PagerButtonUrlPattern))
                return string.Format(PagerButtonUrlPattern, pageIndex);

            if (HttpContext.Current.Request.Url.AbsoluteUri.IndexOf("?") == -1)
            {
                return HttpContext.Current.Request.Url.AbsoluteUri.ToString() + string.Format("?{0}={1}", PageIndexQueryString, pageIndex);
            }
            else
            {
                if (HttpContext.Current.Request.Url.AbsoluteUri.IndexOf(PageIndexQueryString + "=") == -1)
                    return HttpContext.Current.Request.Url.AbsoluteUri.ToString() + string.Format("&{0}={1}", PageIndexQueryString, pageIndex);
                else
                    return Regex.Replace(HttpContext.Current.Request.Url.AbsoluteUri.ToString(), PageIndexQueryString + @"=(\d+\.?\d*|\.\d+)", PageIndexQueryString + "=" + pageIndex);
            }
        }


        /// <summary>
        /// 是否显示 First 按钮
        /// </summary>
        protected virtual bool ShowFirst
        {
            get
            {
                if (Mode == PagerMode.NextPreviousFirstLast || Mode == PagerMode.NumericFirstLast || Mode == PagerMode.NumericNextPreviousFirstLast)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// 是否显示 Last 按钮
        /// </summary>
        protected virtual bool ShowLast
        {
            get
            {
                if (Mode == PagerMode.NextPreviousFirstLast || Mode == PagerMode.NumericFirstLast || Mode == PagerMode.NumericNextPreviousFirstLast)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// 是否显示 Previous 按钮
        /// </summary>
        protected virtual bool ShowPrevious
        {
            get
            {
                if (Mode == PagerMode.NextPrevious || Mode == PagerMode.NextPreviousFirstLast || Mode == PagerMode.NumericNextPreviousFirstLast)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// 是否显示 Previous 按钮
        /// </summary>
        protected virtual bool ShowNext
        {
            get
            {
                if (Mode == PagerMode.NextPrevious || Mode == PagerMode.NextPreviousFirstLast || Mode == PagerMode.NumericNextPreviousFirstLast)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// 是否显示 Numeric 按钮
        /// </summary>
        protected virtual bool ShowNumeric
        {
            get
            {
                if (Mode == PagerMode.Numeric || Mode == PagerMode.NumericFirstLast || Mode == PagerMode.NumericNextPrevious || Mode == PagerMode.NumericNextPreviousFirstLast)
                    return true;
                else
                    return false;
            }
        }

        #endregion


        #region IPager 成员

        int _pageIndex = -2;
        /// <summary>
        /// 当前页序号
        /// </summary>
        public virtual int PageIndex
        {
            get
            {
                if (_pageIndex == -2)
                {
                    if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString[PageIndexQueryString]))
                        _pageIndex = int.Parse(HttpContext.Current.Request.QueryString[PageIndexQueryString]) - 1;
                    else
                        _pageIndex = -1;
                }

                if (_pageIndex < 0)
                    return 0;
                else
                    return _pageIndex;
            }
            set { _pageIndex = value; }
        }

        /// <summary>
        /// 总记录数
        /// </summary>
        public int TotalRecords
        {
            get { return (int)(ViewState["TotalRecords"] ?? 0); }
            set { ViewState["TotalRecords"] = value; }
        }

        /// <summary>
        /// 每页最多显示的记录数
        /// </summary>
        public int PageSize
        {
            get { return (int)(ViewState["PageSize"] ?? 20); }
            set { ViewState["PageSize"] = value; }
        }

        /// <summary>
        /// 总页数
        /// </summary>
        public int TotalPages
        {
            get
            {
                int totalPagesAvailable;

                if (TotalRecords == 0 || PageSize == 0)
                    return 0;

                // First calculate the division
                //
                totalPagesAvailable = TotalRecords / PageSize;

                // Now do a mod for any remainder
                //
                if ((TotalRecords % PageSize) > 0)
                    totalPagesAvailable++;

                return totalPagesAvailable;
            }
        }

        /// <summary>
        /// 当前页码
        /// </summary>
        public int CurrentPage
        {
            get { return this.PageIndex + 1; }
        }

        #endregion
    }

}
